﻿// copyright (c) 2025 author:fio66<fio66@foxmail.com>. All rights reserved.
// date: 2025-09-07 20:20:46

#include <combaseapi.h>

#include <atomic>
#include <filesystem>
#include <iostream>
#include <thread>
#include <variant>
#include <string>


#include "src/ffmpeg_warpper_export.h"

static std::atomic_bool run_demuxing_ = true;

// 测试GetMediaInfo接口
void TestGetMediaInfo(fio66::Demuxer* demuxer) {
    std::cout << "\n=== Testing GetMediaInfo ===" << std::endl;
    
    // 测试获取音频信息
    try {
        auto audio_result = demuxer->GetMediaInfo(fio66::MediaType::kAudio);
        if (audio_result.has_value()) {
            auto audio_info = std::get<fio66::AudioInfo>(audio_result.value());
            std::cout << "Audio Info:" << std::endl;
            std::cout << "  Sample Rate: " << audio_info.sample_rate << " Hz" << std::endl;
            std::cout << "  Channels: " << audio_info.channels << std::endl;
            std::cout << "  Bit Depth: " << audio_info.bit_depth << " bits" << std::endl;
            std::cout << "  Codec Name: " << audio_info.codec_name << std::endl;
        } else {
            std::cout << "Failed to get audio info: Wrong variant type" << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "Exception when getting audio info: " << e.what() << std::endl;
    }
    
    // 测试获取视频信息
    try {
        auto video_result = demuxer->GetMediaInfo(fio66::MediaType::kVideo);
        if (video_result.has_value()) {
            auto video_info = std::get<fio66::VideoInfo>(video_result.value());
            std::cout << "Video Info:" << std::endl;
            std::cout << "  Width: " << video_info.width << " px" << std::endl;
            std::cout << "  Height: " << video_info.height << " px" << std::endl;
            std::cout << "  Frame Rate: " << video_info.frame_rate << " fps" << std::endl;
            std::cout << "  Codec Name: " << video_info.codec_name << std::endl;
        } else {
            std::cout << "Failed to get video info: Wrong variant type" << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "Exception when getting video info: " << e.what() << std::endl;
    }
    
    std::cout << "===========================\n" << std::endl;
}

class MediaDataCallbackImpl : public fio66::MediaDataCallback {
 public:
   MediaDataCallbackImpl(fio66::Demuxer* demuxer) :demuxer_(demuxer) {}
  ~MediaDataCallbackImpl() = default;
  void OnRecieveMediaData(fio66::MediaDataType type, uint8_t* data, size_t size) final {
    if(fio66::MediaDataType::kMediaDataStart == type){
        std::cout << "MediaDataStart" << std::endl;
        audio_device_ = fio66::CreateAudioDevice();
        audio_device_->Create(std::get<fio66::AudioInfo>(demuxer_->GetMediaInfo(fio66::MediaType::kAudio).value()));
    }else if(fio66::MediaDataType::kMediaDataEnd == type){
        // run_demuxing_ = false;
        std::cout << "MediaDataEnd" << std::endl;
        // audio_device_.reset();

    }else if(fio66::MediaDataType::kVideoData == type){
        std::cout << "VideoData" << std::endl;
    }else if(fio66::MediaDataType::kAudioData == type){
      static bool first = true;
      if (first) {
        first = false;
        return;
      }
        audio_device_->SetData(std::span<uint8_t>(data, size));

        std::cout << "AudioData" << std::endl;
    }
  }
  private:
    fio66::Demuxer* demuxer_;
    std::unique_ptr<fio66::AudioDevice> audio_device_;
};

int main() {
    std::cout << "Testing ffmpeg_wrapper library..." << std::endl;
    CoInitializeEx(NULL, NULL);
    // 获取并输出当前运行目录
    try {
        std::filesystem::path current_path = std::filesystem::current_path();
        std::cout << "Current working directory: " << current_path.string() << std::endl;
    } catch (const std::filesystem::filesystem_error& e) {
        std::cerr << "Failed to get current directory: " << e.what() << std::endl;
    }
    
    auto demuxer = fio66::CreateDemuxer();
    if(demuxer){
        bool result = demuxer->Demuxing("./test.mp3", new MediaDataCallbackImpl(demuxer.get()));
        
        if (!result) {
          return -1;
        }
        
        // 测试GetMediaInfo接口
        TestGetMediaInfo(demuxer.get());
    }

    while (run_demuxing_) {
      std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

    std::cout << "Test completed successfully!" << std::endl;
    
    return 0;
}